package org.dromara.tearoom.dubbo;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.BeanUtils;
import org.dromara.tearoom.api.RemoteCouponService;
import org.dromara.tearoom.api.RemoteHtlOrderService;
import org.dromara.tearoom.api.domain.bo.RemoteHtlOrderBo;
import org.dromara.tearoom.api.domain.vo.RemoteCoupVo;
import org.dromara.tearoom.api.domain.vo.RemoteHtlOrderVo;
import org.dromara.tearoom.domain.TerCoupon;
import org.dromara.tearoom.domain.TerOrder;
import org.dromara.tearoom.domain.enums.CouponPlateTypeEnum;
import org.dromara.tearoom.domain.enums.CouponProductScopeTypeEnum;
import org.dromara.tearoom.domain.enums.CouponStatusEnum;
import org.dromara.tearoom.domain.enums.CouponTypeEnum;
import org.dromara.tearoom.domain.vo.TerCouponVo;
import org.dromara.tearoom.domain.vo.TerGroupBuyVo;
import org.dromara.tearoom.domain.vo.TerOrderVo;
import org.dromara.tearoom.domain.vo.TerRoomDetailsVo;
import org.dromara.tearoom.mapper.TerCouponMapper;
import org.dromara.tearoom.mapper.TerGroupBuyMapper;
import org.dromara.tearoom.service.ITerCouponService;
import org.dromara.tearoom.util.WeekMaskUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;

import static org.dromara.common.core.utils.CollectionUtils.convertList;

/**
 * 优惠劵服务实现类
 */
@RequiredArgsConstructor
@Service
@DubboService
public class RemoteCouponServiceImpl implements RemoteCouponService {

    private final ITerCouponService terCouponService;
    private final TerCouponMapper baseMapper;
    private final TerGroupBuyMapper groupBuyMapper;
    @DubboReference
    private RemoteHtlOrderService remoteHtlOrderService;
    /**
     * 批量作废优惠劵
     */
    @Override
    public void expireCoupon() {
        terCouponService.expireCoupon();
    }
    @Override
    public RemoteHtlOrderVo calculatePrice(RemoteHtlOrderVo orderVo) {
        //加载用户的优惠劵列表
        List<TerCouponVo> coupons = baseMapper.selectVoList(new LambdaQueryWrapper<TerCoupon>().eq(TerCoupon::getUserId, orderVo.getUserId()).eq(TerCoupon::getStatus, CouponStatusEnum.UNUSED.getStatus()));
        coupons.removeIf(coupon -> DateUtil.compare(new Date(), coupon.getValidEndTime()) > 0);
        //计算优惠劵的使用条件
        if (ObjectUtil.isNotEmpty(orderVo.getCouponId())) {
            RemoteHtlOrderVo.Coupon couponBO = CollUtil.findOne(orderVo.getCoupons(), item -> item.getId().equals(orderVo.getCouponId()));
            TerCouponVo coupon = CollUtil.findOne(coupons, item -> item.getId().equals(orderVo.getCouponId()));
            if (couponBO == null || coupon == null) {
                throw new ServiceException("优惠劵不存在");
            }
            if (Boolean.FALSE.equals(couponBO.getMatch())) {
                throw new ServiceException(couponBO.getMismatchReason());
            }
            //计算优惠金额
            Integer couponPrice = terCouponService.getCouponPrice(coupon, orderVo.getTotalPrice());
            orderVo.setCouponPrice(Long.valueOf(couponPrice));
            orderVo.setPrepayAmount(orderVo.getTotalPrice() - couponPrice);
            //记录使用的优惠劵
            orderVo.setCouponId(String.valueOf(orderVo.getCouponId()));
        } else {
            orderVo.setPrepayAmount(orderVo.getTotalPrice());
            orderVo.setRevenue(orderVo.getTotalPrice());
        }
        return orderVo;
    }
    @Override
    public List<RemoteCoupVo> queryCoupList(Long userId ,Integer totalPrice) {
        //加载用户的优惠劵列表
        List<TerCouponVo> coupons = baseMapper.selectVoList(new LambdaQueryWrapper<TerCoupon>().eq(TerCoupon::getUserId, userId).eq(TerCoupon::getStatus, CouponStatusEnum.UNUSED.getStatus()));

        coupons.removeIf(coupon -> DateUtil.compare(new Date(), coupon.getValidEndTime()) > 0);
        // 计算优惠劵的使用条件

        return convertList(coupons, coupon -> {
            RemoteCoupVo matchCoupon = BeanUtils.toBean(coupon, RemoteCoupVo.class);
            matchCoupon.setMatch(false);
            //优惠劵未到使用时间
            if (DateUtil.compare(new Date(), coupon.getValidStartTime()) < 0) {
                matchCoupon.setMismatchReason("优惠劵未到使用时间");
                return matchCoupon;
            }
            //差 %1$,.2f 元可用优惠劵
            if (totalPrice < coupon.getUsePrice()) {
                matchCoupon.setMismatchReason(String.format("差 %1$,.2f 元可用优惠劵", (coupon.getUsePrice() - totalPrice) / 100D));
                return matchCoupon;
            }
            //优惠金额超过订单金额
            Integer couponPrice = terCouponService.getCouponPrice(coupon, totalPrice);
            if (couponPrice >= totalPrice) {
                matchCoupon.setMismatchReason("优惠金额超过订单金额");
                return matchCoupon;
            }
            // 检查当前星期是否可用
            if (coupon.getValidDays() != null && coupon.getValidDays() != 0) {
                // 使用位运算检查当前星期是否可用
                if (WeekMaskUtils.isNowValid(coupon.getValidDays())) {
                    matchCoupon.setMismatchReason("当前日期不可使用该优惠券");
                    return matchCoupon;
                }
            }
            //满足条件
            matchCoupon.setMatch(true);
            return matchCoupon;
        });
    }
}
